package com.ruoyi.record.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.record.common.RecordConstant;
import com.ruoyi.record.domain.WordHearRecord;
import com.ruoyi.record.domain.WordStudyRecord;
import com.ruoyi.record.domain.WordStudyStepProgress;
import com.ruoyi.record.domain.WordTestRecord;
import com.ruoyi.record.service.IWordStudyStepProgressService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.Objects;

@Slf4j
@Service
public class WordRecordCommonService {

    private static final Long admin = 1L;

    private final ISysDeptService deptService;

    private final ISysUserService userService;

    private final RedisCache redisCache;

    private final IWordStudyStepProgressService progressService;

    public WordRecordCommonService(@Lazy IWordStudyStepProgressService progressService, ISysDeptService deptService, ISysUserService userService, RedisCache redisCache) {
        this.progressService = progressService;
        this.deptService = deptService;
        this.userService = userService;
        this.redisCache = redisCache;
    }

    /**
     * 处理是否有未完成任务
     * jsonObject 记录表中测试或学习计算出的数据
     */
    public void handleProcess(JSONObject jsonObject, Long userId) {
        boolean containTask = containTodoTask(Math.toIntExact(userId));
        if (containTask) {
            String redisKey = RecordConstant.TASK_DATA_TO_REDIS + userId;
            JSONObject todoTaskData = getTodoTaskData(redisKey, jsonObject);
            log.info("系统检测分配的任务:{}", todoTaskData.get("result"));
            JSONObject obj = todoTaskData.getJSONObject("obj");
            BigDecimal rate = obj.getBigDecimal("rate");
            if (todoTaskData.getBoolean("result")) {
                if (rate == null) {
                    rate = new BigDecimal("0.8");
                }
                if (jsonObject.getBigDecimal("rate").compareTo(RecordConstant.TASK_COMPLETE_RATE) > -1 ||
                        rate.compareTo(jsonObject.getBigDecimal("rate")) < 1) {
                    WordStudyStepProgress progress = new WordStudyStepProgress();
                    progress.setId(obj.getLong("id"));
                    progress.setActive(RecordConstant.ACTIVE_COMPLETE);
                    progressService.updateWordStudyStepProgress(progress);
                    delTodoTaskData(redisKey, obj);
                }
            }
            log.info("系统记录用户:{}的任务,完成率:{},要求的最低比率:{}", userId, jsonObject.getBigDecimal("rate"), rate);
        }
    }

    /**
     * 清除数据
     * 或者删除多余数据
     */
    public void delTodoTaskData(String redisKey, JSONObject obj) {
        log.info("redis-key-delete:{}", redisKey);
        Object cacheObject = redisCache.getCacheObject(redisKey);
        if (cacheObject == null) {
            log.info("redis-key-is-null:{}", redisKey);
            return;
        }
        JSONArray jsonArray = JSONArray.parseArray(cacheObject.toString());
        Iterator<Object> iterator = jsonArray.iterator();
        if (obj.containsKey(RecordConstant.TASK_CANCEL_ID)) {
            while (iterator.hasNext()) {
                JSONObject jsonObject = (JSONObject) iterator.next();
                if (Objects.equals(jsonObject.getInteger("id"), obj.getInteger(RecordConstant.TASK_CANCEL_ID))) {
                    iterator.remove();
                }
            }
        } else {
            while (iterator.hasNext()) {
                JSONObject jsonObject = (JSONObject) iterator.next();
                if (jsonObject.equals(obj)) {
                    iterator.remove();
                }
            }
        }
        if (!jsonArray.isEmpty()) {
            log.info("还有未完成的任务:{},剩余:{}", redisKey, jsonArray.size());
            redisCache.setCacheObject(redisKey, jsonArray);
        } else {
            log.info("已完成全部的任务:{},值将删除", redisKey);
            redisCache.deleteObject(redisKey);
        }
    }

    /**
     * 获取判断并提取数据
     */
    public JSONObject getTodoTaskData(String redisKey, JSONObject json) {
        Object cacheObject = redisCache.getCacheObject(redisKey);
        log.info("redis-key-select:{}", redisKey);
        if (cacheObject == null) {
            log.info("未查询到key:{}的数据", redisKey);
            return JSONObject.of("result", false);
        }
        JSONObject obj = new JSONObject();
        JSONObject jsonObj = new JSONObject();
        JSONArray jsonArray = JSONArray.parseArray(cacheObject.toString());
        boolean result = false;
        int index = 1;
        for (Object object : jsonArray) {
            JSONObject jsonObject = (JSONObject) object;
            //处理无组的数据
            boolean bool = false;
            if (json.containsKey("book") && json.containsKey("unit") &&
                    jsonObject.getString("book") != null && jsonObject.getString("unit") != null) {
                bool = json.getString("book").equals(jsonObject.getString("book")) &&
                        json.getString("unit").equals(jsonObject.getString("unit")) &&
                        json.getString("type").equals(jsonObject.getString("type"));
            }
            //处理有组的数据
            boolean boolGroup = false;
            if (json.containsKey("group") && jsonObject.getString("group") != null) {
                boolGroup = json.getString("group").equals(jsonObject.getString("group")) &&
                        json.getString("type").equals(jsonObject.getString("type"));
            }
            result = bool || boolGroup;
            log.info("本次{}-检查结果-,有组:{},无组:{}", index++, bool, boolGroup);
            if (result) {
                jsonObj = jsonObject;
                break;
            }
        }
        obj.put("result", result);
        obj.put("obj", jsonObj);
        return obj;
    }

    /**
     * 获取数据
     * 缓冲数据
     */
    public void getAndSet(WordStudyStepProgress progress) {
        String redisKey = RecordConstant.TASK_DATA_TO_REDIS + progress.getStudentId();
        Object cacheObject = redisCache.getCacheObject(redisKey);
        log.info("redis-key-select:{}", redisKey);

        if (cacheObject == null) {
            log.info("未查询到key:{}的数据", redisKey);
            JSONObject jsonObject = getJSONObj(progress);
            JSONArray jsonArray = new JSONArray();
            jsonArray.add(jsonObject);
            // 局部禁用@type，添加WriteClassName.disable()
            redisCache.setCacheObject(redisKey, jsonArray);
        } else {
            log.info("数据-key:{}-已存在数据", redisKey);
            JSONArray jsonArray = JSONArray.parseArray(cacheObject.toString());
            JSONObject jsonObject = getJSONObj(progress);
            jsonArray.add(jsonObject);
            log.info("更新后的缓冲数据-key:{}-长度:{}", redisKey, jsonArray.size());
            redisCache.setCacheObject(redisKey, jsonArray);
        }
    }

    private JSONObject getJSONObj(WordStudyStepProgress progress) {
        JSONObject jsonObject = new JSONObject();

        String data = progress.getContent();
        if (data != null && !data.isEmpty()) {
            if (progress.getTitle() == null || progress.getTitle().equals("0")) {
                // 高中 + 初中
                String message = data.substring(data.indexOf('-') + 1);
                String book = message.substring(0, message.indexOf(','));
                String unit = message.substring(message.lastIndexOf('-') + 1);

                jsonObject.put("book", book.replace("'", ""));
                jsonObject.put("unit", unit.replace("'", ""));
            } else {
                jsonObject.put("group", progress.getTitle());
            }
        }
        jsonObject.put("user", Math.toIntExact(progress.getStudentId()));
        jsonObject.put("id", Math.toIntExact(progress.getId()));
        jsonObject.put("rate", progress.getRate());
        jsonObject.put("end", progress.getEnd());
        jsonObject.put("main", progress.getMain());
        jsonObject.put("people", progress.getPeople());
        jsonObject.put("type", progress.getType());
        jsonObject.put("time", DateUtils.getLocalTime());
        return jsonObject;
    }

    public boolean containTodoTask(int userId) {
        Boolean hasKey = redisCache.hasKey(RecordConstant.TASK_DATA_TO_REDIS + userId);
        log.info("系统检测是否包含用户ID:{},结果:{}", userId, hasKey);
        return hasKey;
    }

    public WordTestRecord selectList(WordTestRecord entity) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        Long deptId = loginUser.getDeptId();
        SysDept sysDept = deptService.selectDeptById(deptId);
        if (!userId.equals(admin)) {
            entity.setUserSchool(sysDept.getDeptName());
        }
        return entity;
    }

    /**
     * 通过用户ID获取部门名称
     */
    public String getDeptName(Long userId) {
        Long deptId;
        if (userId == null) {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            deptId = loginUser.getDeptId();
        } else {
            SysUser sysUser = userService.selectUserById(userId);
            deptId = sysUser.getDeptId();
        }
        SysDept sysDept = deptService.selectDeptById(deptId);
        return sysDept.getDeptName();
    }

    public WordHearRecord selectList(WordHearRecord entity) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        Long deptId = loginUser.getDeptId();
        SysDept sysDept = deptService.selectDeptById(deptId);
        if (!userId.equals(admin)) {
            entity.setUserSchool(sysDept.getDeptName());
        }
        return entity;
    }

    public WordHearRecord insertList(WordHearRecord entity) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        Long deptId = loginUser.getDeptId();
        SysDept sysDept = deptService.selectDeptById(deptId);
        entity.setUserSchool(sysDept.getDeptName());
        entity.setUserName(loginUser.getUsername());
        entity.setUserId(userId);
        return entity;
    }

    public WordStudyRecord insertList(WordStudyRecord entity) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        Long deptId = loginUser.getDeptId();
        SysDept sysDept = deptService.selectDeptById(deptId);
        entity.setUserSchool(sysDept.getDeptName());
        entity.setUserName(loginUser.getUsername());
        entity.setUserId(userId);
        return entity;
    }

    public WordTestRecord insertList(WordTestRecord entity) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        Long deptId = loginUser.getDeptId();
        SysDept sysDept = deptService.selectDeptById(deptId);
        entity.setUserSchool(sysDept.getDeptName());
        entity.setUserName(loginUser.getUsername());
        entity.setUserId(userId);
        return entity;
    }

    public WordStudyRecord selectList(WordStudyRecord entity) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        Long deptId = loginUser.getDeptId();
        SysDept sysDept = deptService.selectDeptById(deptId);
        if (!userId.equals(admin)) {
            entity.setUserSchool(sysDept.getDeptName());
        }
        return entity;
    }
}
